package edu.gatech.coc.sirana.graph;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

import net.util.Debug;
import net.util.Out;

import edu.gatech.coc.sirana.parser.ClientLogItem;
import edu.gatech.coc.sirana.parser.ClientLogParser;
import edu.gatech.coc.sirana.parser.OneWebPageInteractionLogParser;
import edu.gatech.coc.sirana.util.CONSTANT;

/**
 * Successive Repeated Cycles.
 * @author Paul
 *
 */
public class CycleDetector {	
	
	
	/**
	 * 
	 * @param interactionList
	 * @return All repeated sequences: 123123123 results in 123,123,123, 231, 231, 321, 321.
	 */
	public ArrayList<InteractionCycle> findCyclesAndRepeatedSequence(ArrayList<ClientLogItem> interactionList){
//		Debug.println("\n---findCycles....");
		ArrayList<InteractionCycle> allCycles = new ArrayList<InteractionCycle>();
		
		OnlineGraph og = new OnlineGraph();
		ArrayList<InteractionCycle> cycleList = og.detectRecursiveInteractionCircles(interactionList);
		
		for (InteractionCycle ic : cycleList){
//			Debug.println("\n check cycle:\n\t" + ic.toString());
			if (ic.isInteractiveCycle()){				
				allCycles.add(ic);
			}
		}	
				
//		Debug.println("\n----findSequences....");
		ArrayList<InteractionCycle> sequenceList = findAllSequence(interactionList);		
		ArrayList<InteractionCycle> nonRedundantSeqences = og.removeRedundantCycles(sequenceList);		
		for (InteractionCycle ic: nonRedundantSeqences){
//			Debug.println("===A seq: \n\t" + ic.toString());
		}
				
		for (InteractionCycle seq : nonRedundantSeqences){
			if (!seq.isIn(cycleList)){
				allCycles.add(seq);
			}
		}
		
		Collections.sort(allCycles);
		
//		Debug.println("\n----All cycles and seqs: ");
//		for(InteractionCycle ic : allCycles){
//			Debug.println("\n===ALL cyc-sequ:\n\t" + ic.toString());
//		}
//		
		
//		Debug.println("findCyclesAndRepeatedSequence DONE===\n");
		return allCycles;
	}
	
	public ArrayList<InteractionCycle> findAllSequence(ArrayList<ClientLogItem> interactionList){
		ArrayList<InteractionCycle> sequenceList = new ArrayList<InteractionCycle>();
		Util util = new Util();
		ArrayList<String> checkedActions = new ArrayList<String>();
		for (int i=0; i<interactionList.size(); i++){
			ClientLogItem pointerItem = interactionList.get(i);
			String pointerAction = pointerItem.findAction();			
			int pointerActionLastPos = checkedActions.lastIndexOf(pointerAction);
			
			if (pointerActionLastPos >= 0) {						
				InteractionCycle ic = util.createICfromSublist(pointerActionLastPos, i, interactionList);
				util.addInteractionCycle(sequenceList, ic);
			}
			
			checkedActions.add(pointerAction);
		}
		
		return sequenceList;
	}
	
	public ArrayList<SRCycles> findSRCycles(ArrayList<InteractionCycle> allCycles, OnlineGraph og){
//		Debug.println("\n....findSuccessiveRepeatedCircles from " + allCycles.size() + " circles...\n");
		
		ArrayList<SRCycles> srcList = new ArrayList<SRCycles>();
		
		ArrayList<Integer> checkedPosList = new ArrayList<Integer>();
		for (int i=0; i<allCycles.size()-1; i++){
			if (checkedPosList.contains(i)) continue;
			
			ArrayList<InteractionCycle> src = new ArrayList<InteractionCycle>();
			
			InteractionCycle pointerCycle = allCycles.get(i);
			src.add(pointerCycle);
			checkedPosList.add(i);
//			Debug.println("---check cycles :---\n" + pointerCycle.findItemIds());
						
			for (int j=i+1; j<allCycles.size(); j++){
				InteractionCycle nextCycle = allCycles.get(j);
				
//				if (nextCycle.isApproximateRSCycleTo(pointerCycle, og))
				if (nextCycle.isExactRSCycleTo(pointerCycle))
				{
					src.add(nextCycle);
					checkedPosList.add(j);
					pointerCycle=nextCycle;
				}
			}
			
			//if (src.size()==0) src.add(pointerCycle);									
			if (src.size() > 1)
				srcList.add(new SRCycles(src));
		}		
		
		return srcList;		
	}
	
	
	
}
